Skip to content

fix(compiler): repair generic dictionary dispatch for pointer-constraint receivers - #161

Merged
paralin merged 1 commit into
masterfrom
fix/generic-dict-unmarshal-dispatch
Aug 24, 2026
Merged

fix(compiler): repair generic dictionary dispatch for pointer-constraint receivers#161
paralin merged 1 commit into
masterfrom
fix/generic-dict-unmarshal-dispatch

Conversation

@paralin

@paralin paralin commented Aug 24, 2026

Copy link
Copy Markdown
Member

Interface-constraint generic methods lowered a property-keyed dispatch lambda that called the method directly on the receiver value. When Go code converts the address of a variable to the constraint's pointer type-set element (M(&msg) over an interface embedding *T), the runtime receiver arrived as a VarRef wrapper with no method properties, so the call failed at runtime with TypeError: is not a function.

Struct receivers in dictionary method lambdas are now unwrapped through the runtime pointerValue helper before the property-keyed call; class instances pass through unchanged and interface descriptors keep their existing shape.

The same chain exposed a second lowering gap: an explicit instantiation that leaves trailing type parameters to constraint inference, such as decodeLocalPairing[*pairingOffer] over [M localPairingMessage[T], T any], emitted type arguments only for the explicitly written parameter. The generic body then resolved the remaining parameter's zero value as null and dispatched on nil, surfacing downstream as index-out-of-range failures. The lowering now reads the full argument list recorded by go/types Instances when explicit arguments run out.

compilerSemanticsVersion is bumped so cached artifacts recompile with the new dispatch shape instead of serving pre-fix output on warm builds.

…int receivers

Interface-constraint generic methods lowered a property-keyed dispatch
lambda that called the method directly on the receiver value. When the
caller converted the address of a variable to the constraint's pointer
type-set element, the runtime receiver was a VarRef wrapper, so the call
failed with TypeError: <Method> is not a function.

Unwrap struct receivers through pointerValue in the dictionary lambdas;
class instances pass through unchanged. Interface descriptors keep their
existing shape.

The same chain exposed a second lowering gap: an explicit instantiation
that leaves trailing type parameters to constraint inference, such as
decodeLocalPairing[*pairingOffer] over [M localPairingMessage[T], T any],
emitted type arguments only for the explicitly written parameter, so the
body resolved T's zero value as null and dispatched on nil. Read the full
argument list recorded by go/types Instances when explicit arguments run
out.

Bump compilerSemanticsVersion so cached artifacts recompile with the new
dispatch shape.

Signed-off-by: Christian Stewart <christian@aperture.us>
@paralin
paralin merged commit f295c0f into master Aug 24, 2026
9 checks passed
@paralin
paralin deleted the fix/generic-dict-unmarshal-dispatch branch August 24, 2026 17:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant